/**
 * Created by Administrator on 2014/4/7.
 * 最核心的算法类
 */
var Calculator = function () {

}
/**
 *填充格子数据，但是是有序的，下一步应该是打乱顺序
 * @param typeArr
 * @return
 *
 */
Calculator.prototype.getAllPicArr = function (typeArr) {
    var resultArr = [];
    var totalIndex = 0;
    var typeIndex = 0;
    while (totalIndex + 2 <= Data.row * Data.line) {
        if (typeIndex >= typeArr.length) {
            typeIndex = 0;
        }
        resultArr.push(typeArr[typeIndex], typeArr[typeIndex]);
        typeIndex++;
        totalIndex = totalIndex + 2;
    }
    return resultArr;
}
/**
 *获得type 数组
 * @param num
 * @return
 *
 */
Calculator.prototype.getPicTypeArr = function (num) {
    var tempArr = [];
    var resultArr = null;
    var totalArr = new Array(Data.totalPics);
    var index = 1;
    while (index <= totalArr.length) {
        totalArr[index - 1] = index;
        index++;
    }
    while (index < num) {
        if (tempArr.length == 0) {
            tempArr = totalArr.concat();
        }
        resultArr.push(tempArr.splice(int(tempArr.length * Math.random()), 1));
        index++;
    }
    return resultArr;
}
/**
 *设置相邻的元素
 * @param mapArr
 * @param fillArr
 * @param minPairs
 *
 */
Calculator.prototype.setConnectPicArr = function (mapArr, fillArr, minPairs) {
    var randomRow = 0;
    var randomLine = 0;
    var tempPosArr = null;
    var el;
    var tempRow = 0;
    var tempLine = 0;
    var dirArr = [
        [-1, 0],
        [1, 0],
        [0, -1],
        [0, 1]
    ];
    if (minPairs > (Data.row * Data.line)) {
        minPairs = int(((Data.row * Data.line) / 2));
    }

    var testingCount = 0; //进行了几次尝试
    //有几对是相邻的？
    for (var i = 0; i < minPairs; i++) {
        if (testingCount >= 10000) {
            break;
        }
        randomRow = (Data.row * Math.random());
        randomLine = (Data.line * Math.random());
        if (mapArr[randomRow][randomLine] == 0) {
            tempPosArr = [];
            for (var dir in dirArr) {
                tempRow = (randomRow + int(dirArr[dir][0]));
                tempLine = (randomLine + int(dirArr[dir][1]));
                if (tempRow < 0 || tempRow > Data.row - 1 || tempLine < 0 || tempLine > Data.line - 1) {
                } else {
                    if (mapArr[tempRow][tempLine] == 0) {
                        tempPosArr.push([tempRow, tempLine]);
                    }
                }
            }
            if (tempPosArr.length == 0) {
                i--;
                testingCount++;
                continue;
            }
            testingCount = 0;
            el = fillArr.shift();
            mapArr[randomRow][randomLine] = el;
            var randomPos = tempPosArr[int((tempPosArr.length * Math.random()))];
            el = fillArr.shift();
            mapArr[randomPos[0]][randomPos[1]] = el;
        } else {
            i--;
            testingCount++;
        }
    }
}
/**
 *判断一根线的情况
 * @param mapArr
 * @param row1
 * @param line1
 * @param row2
 * @param line2
 * @return
 *
 */
Calculator.prototype.checkLine = function (mapArr, row1, line1, row2, line2) {
    var line = 0;
    var row = 0;
    if (!(row1 == row2) && !(line1 == line2)) {
        trace("checkLine只能检测直线上的点!");
        return false;
    }
    if (row1 == row2 && line1 == line2) //同一个点，看是否相通
    {
        return mapArr[row1][line1] == 0;
    }
    if (row1 == row2) //同行
    {
        line = Math.min(line1, line2); //最小点
        while (line <= Math.max(line1, line2)) {
            if (mapArr[row1][line] > 0) {
                return false;
            }
            line++;
        }
        return true;
    }
    row = Math.min(row1, row2);
    while (row <= Math.max(row1, row2)) {
        if (mapArr[row][line1] > 0) {
            return false;
        }
        row++;
    }
    return true;
}
/**
 *长度
 * @param pos
 * @return
 *
 */
Calculator.prototype.getPathPointNumber = function (pos) {
    var totalLen = 0;
    var nextRow = 0;
    var nextLine = 0;
    var row = pos[0][0];
    var line = pos[0][1];
    var i = 1;
    while (i < pos.length) {
        nextRow = pos[i][0];
        nextLine = pos[i][1];
        totalLen = totalLen + (nextRow == row ? Math.abs(line - nextLine) : Math.abs(row - nextRow));
        row = nextRow;
        line = nextLine;
        i++;
    }
    return totalLen;
}
/**
 * 核心方法，判断是否2点想通，并返回路径
 * @param mapArr
 * @param selectedTilePos
 * @param tilePos
 * @returns {*}
 */
Calculator.prototype.isConnected = function (mapArr, selectedTilePos, tilePos) {
    var resultArr = [];
    var row = 0;
    var line = 0;
    var index = 0;
    if (selectedTilePos.r == tilePos.r) //横向相同，判定挨着的情况
    {
        if (Math.abs(selectedTilePos.l - tilePos.l) <= 1 ||
            (this.checkLine(mapArr, selectedTilePos.r, selectedTilePos.l > tilePos.l ? selectedTilePos.l - 1 : selectedTilePos.l + 1, tilePos.r, tilePos.l > selectedTilePos.l ? tilePos.l - 1 : tilePos.l + 1))) {//想通 的，返回2点，用于划线
            return [
                [selectedTilePos.r, selectedTilePos.l],
                [tilePos.r, tilePos.l]
            ];
        }
    } else if (selectedTilePos.l == tilePos.l) //纵向相同
    {
        if (Math.abs(selectedTilePos.r - tilePos.r) <= 1 ||
            (this.checkLine(mapArr, selectedTilePos.r > tilePos.r ? selectedTilePos.r - 1 : selectedTilePos.r + 1, selectedTilePos.l, tilePos.r > selectedTilePos.r ? tilePos.r - 1 : tilePos.r + 1, tilePos.l))) {
            return [
                [selectedTilePos.r, selectedTilePos.l],
                [tilePos.r, tilePos.l]
            ];
        }
    }
    //不同行也不同列,则判断四周的情况，
    //先判断row+1情况
    row = selectedTilePos.r + 1;
    while (row < Data.row + 2) {
        if (mapArr[row][selectedTilePos.l] > 0) //如果当前点不通则直接返回，进行下一步检测
        {
            break;
        }
        if (this.checkLine(mapArr, row, selectedTilePos.l, row, tilePos.l > selectedTilePos.l ? tilePos.l - 1 : tilePos.l + 1)) {//检测当前点横向是否通，如果通，这玩下执行，否则，row继续增加
            if (row == tilePos.r) //假如当前row 和第二点的row相同
            {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [row, selectedTilePos.l],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
            if (this.checkLine(mapArr, row, tilePos.l, tilePos.r > row ? tilePos.r - 1 : tilePos.r + 1, tilePos.l)) {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [row, selectedTilePos.l],
                    [row, tilePos.l],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
        }
        row++;
    }
    row = selectedTilePos.r - 1;
    while (row >= 0) {
        if (mapArr[row][selectedTilePos.l] > 0) {
            break;
        }
        if (this.checkLine(mapArr, row, selectedTilePos.l, row, tilePos.l > selectedTilePos.l ? tilePos.l - 1 : tilePos.l + 1)) {
            if (row == tilePos.r) {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [row, selectedTilePos.l],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
            if (this.checkLine(mapArr, row, tilePos.l, tilePos.r > row ? tilePos.r - 1 : tilePos.r + 1, tilePos.l)) {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [row, selectedTilePos.l],
                    [row, tilePos.l],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
        }
        row--;
    }
    line = selectedTilePos.l + 1;
    while (line < Data.line + 2) {
        if (mapArr[selectedTilePos.r][line] > 0) {
            break;
        }
        if (this.checkLine(mapArr, selectedTilePos.r, line, tilePos.r > selectedTilePos.r ? tilePos.r - 1 : tilePos.r + 1, line)) {
            if (line == tilePos.l) {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [selectedTilePos.r, line],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
            if (this.checkLine(mapArr, tilePos.r, line, tilePos.r, tilePos.l > line ? tilePos.l - 1 : tilePos.l + 1)) {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [selectedTilePos.r, line],
                    [tilePos.r, line],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
        }
        line++;
    }
    line = selectedTilePos.l - 1;
    while (line >= 0) {
        if (mapArr[selectedTilePos.r][line] > 0) {
            break;
        }
        if (this.checkLine(mapArr, selectedTilePos.r, line, tilePos.r > selectedTilePos.r ? tilePos.r - 1 : tilePos.r + 1, line)) {
            if (line == tilePos.l) {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [selectedTilePos.r, line],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
            if (this.checkLine(mapArr, tilePos.r, line, tilePos.r, tilePos.l > line ? tilePos.l - 1 : tilePos.l + 1)) {
                resultArr.push([
                    [selectedTilePos.r, selectedTilePos.l],
                    [selectedTilePos.r, line],
                    [tilePos.r, line],
                    [tilePos.r, tilePos.l]
                ]);
                break;
            }
        }
        line--;
    }
    //找到了,有拐点的情况，会找到很多条路径，则找出最优的路径
    if (resultArr.length > 0) {
        index = 0;
        row = 1;
        while (row < resultArr.length) {
            if (resultArr[row].length < resultArr[index].length) {
                index = row;
            }
            else if (this.getPathPointNumber(resultArr[row]) < this.getPathPointNumber(resultArr[index])) {
                index = row;
            }
            row++;
        }
        return resultArr[index];
    }
    return null;
}

/**
 *获得提示数组 返回[]数组代表图片已经翻完了，已经过关了，返回null代表无路可走，必须要重新洗牌
 * @param mapArr
 * @return
 *
 */
Calculator.prototype.getHintResult = function (mapArr) {
    var typeMap;
    var typeArr;
    var type;
    var oneTypeElArr;
    var elIndex;
    var elNextIndex;
    var path;
    typeMap = new Object();
    typeArr = [];
    var row = 0;
    var line = 0;
    while (row < mapArr.length) {
        line = 0;
        while (line < mapArr[row].length) {
            if (mapArr[row][line] != 0) {
                //分类
                if (typeMap[mapArr[row][line]] == null) {
                    typeMap[mapArr[row][line]] = new Array();
                    typeArr.push(mapArr[row][line]);
                }
                typeMap[mapArr[row][line]].push([row, line]);
            }
            line++;
        }
        row++;
    }
    if (typeArr.length <= 0) { //已经没有图片了
        return ([]);
    }
    while (typeArr.length > 0) {
        type = typeArr.splice(int((Math.random() * typeArr.length)), 1);
        oneTypeElArr = typeMap[type];
        elIndex = 0;
        while (elIndex < (oneTypeElArr.length - 1)) {
            elNextIndex = (elIndex + 1);
            while (elNextIndex < oneTypeElArr.length) {
                path = this.isConnected(mapArr, new Pot(oneTypeElArr[elIndex][0], oneTypeElArr[elIndex][1]),
                    new Pot(oneTypeElArr[elNextIndex][0], oneTypeElArr[elNextIndex][1]));
                //一旦找到了一条可以联通的路径，直接返回这条提示
                if (path != null) {
                    return path;
                }
                elNextIndex++;
            }
            elIndex++;
        }
    }
    return null;
}
/**
 * 重新打乱图片顺序
 * @param mapArr
 */
Calculator.prototype.resetPic = function (mapArr) {
    var randomIndex = 0;
    var tempArr = [];
    var row = 0;
    var line = 0;
    while (row < mapArr.length) {
        line = 0;
        while (line < mapArr[row].length) {
            if (mapArr[row][line] > 0) {
                tempArr.push(mapArr[row][line]);
            }
            line++;
        }
        row++;
    }
    row = 0;
    while (row < mapArr.length) {
        line = 0;
        while (line < mapArr[row].length) {
            if (mapArr[row][line] > 0) {
                randomIndex = int(tempArr.length * Math.random());
                mapArr[row][line] = tempArr[randomIndex];
                tempArr.splice(randomIndex, 1);
            }
            line++;
        }
        row++;
    }
}
